import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
/**
 *
 * 
 */
public class PassengerChoice {




   // private Date date;
    private int chosenTime;
    private ArrayList<Journey> journeyOptions;
    private Journey optimal;

    public PassengerChoice(int chosenTime, ArrayList<Journey> journeyOptions) {
        this.chosenTime = chosenTime;
        this.journeyOptions=journeyOptions;
        findOptimal();
       
    }
    public ArrayList getPossibleJourneys(){
        return this.journeyOptions;
    }

    public Journey getOptimal() {
        return this.optimal;
    }
    
        public static ArrayList<Journey> findChangeOptionsFirst(String startArea, String endArea,
            String startStop, String endStop, Date date) {
            ArrayList<Journey> list=new ArrayList<Journey>();
            int endAreaId = BusStopInfo.findAreaByName(endArea);
            int startAreaId = BusStopInfo.findAreaByName(startArea);
            int[] startStops = BusStopInfo.getBusStopsInArea(startAreaId);
            int[] endStops = BusStopInfo.getBusStopsInArea(endAreaId);
            boolean startBusStopsOn358out=true;
            for (int i = 0; i < startStops.length; i++) {
                int[] routes=BusStopInfo.getRoutes(startStops[i]);
                for (int j = 0; j < routes.length; j++)
                    if(routes[j]!=67 && routes[j]!=68)
                        startBusStopsOn358out=false;
            }
            list=findJourneyOptions(startArea, "Marple", startStop, "Navigation Hotel", date);

        return list;
    }


   /**
    * Algorithm to find all possibilities from start to end stop.
    * It is part of the constructor to initialise this.journeyOptions
     */
       public static ArrayList<Journey> findJourneyOptions(String startArea, String endArea,
            String startStop, String endStop, Date date){
            TimetableInfo.timetableKind kind=TimetableInfo.timetableKind(date);
            int endAreaId = BusStopInfo.findAreaByName(endArea);
            int startAreaId = BusStopInfo.findAreaByName(startArea);
            int[] startStops = BusStopInfo.getBusStopsInArea(startAreaId);
            int[] endStops = BusStopInfo.getBusStopsInArea(endAreaId);
            ArrayList<Integer> possibleEnd=new ArrayList<Integer>();
            ArrayList<Integer> possibleStart=new ArrayList<Integer>();

            ArrayList<Journey> journeyOptions=new ArrayList<Journey>();
            ArrayList<Integer> possibleEndRoute=new ArrayList<Integer>();

            for(int i=0; i<startStops.length; i++)
                if(BusStopInfo.getName(startStops[i]).equals(startStop))
                    possibleStart.add(startStops[i]);

            for(int i=0; i<endStops.length; i++)
                if(BusStopInfo.getName(endStops[i]).equals(endStop))
                    possibleEnd.add(endStops[i]);

            for(int i=0; i<possibleEnd.size(); i++){
                int[] r=BusStopInfo.getRoutes(possibleEnd.get(i));
                int k=0;
                while(k<r.length){
                    possibleEndRoute.add(r[k]);
                    k++;
                }
            }

              for(int i=0; i<possibleStart.size(); i++){
                int start=possibleStart.get(i);
                int[] r=BusStopInfo.getRoutes(start);
                int j=0,p=0;
                for(int k=0; k<r.length; k++)
                    while(j<possibleEndRoute.size()){
                        if(r[k]==possibleEndRoute.get(j)){
                            int next=BusStopInfo.getNextStop(start,r[k]);
                            if(next==0)
                                break;
                             while(p<19){
                                next=BusStopInfo.getNextStop(next,r[k]);
                                if(next==0)
                                    break;
                                if(BusStopInfo.getName(next).equals(endStop)){
                                     journeyOptions.add(new Journey(start,
                                             next, r[k], p+2, kind));
                                     break;
                                 }//if
                                p++;
                             }///while
                        }//if
                        j++;
                     }//while
                 } //for

            return journeyOptions;
    }




       /**
 * finds minimum number of stops among Journey possibilities
 * @return
 */
    private ArrayList findShortestJourneys(){
        ArrayList<Journey> leastStops=new ArrayList<Journey>();
        int size=this.journeyOptions.size();
        int[] noOfPossStops=new int[size];
        for (int i = 0; i < noOfPossStops.length; i++)
            noOfPossStops[i]=this.journeyOptions.get(i).getNoOfBusStopsBetween();
        Arrays.sort(noOfPossStops);
        int min=noOfPossStops[0];
        for (Journey i : this.journeyOptions) {
            if(i.getNoOfBusStopsBetween()==min)
                leastStops.add(i);
        }
        return leastStops;
    }


    private void findOptimal() {        
        ArrayList<Journey> leastStops=findShortestJourneys();
        for (Journey journey : leastStops) {
            journey.setDepAndArrivalTime(chosenTime);
        }
        int sizeLeast=leastStops.size();

        if(sizeLeast==1)
            this.optimal=leastStops.get(0);
        else if(sizeLeast>1)
            getFirstAtTheEnd(leastStops);
    }
  

    private void getFirstAtTheEnd(ArrayList<Journey> leastStops) {
        Journey firstAtTheEnd=leastStops.get(0);
        int quickestArrival=firstAtTheEnd.getArrivalTime();
        for (Journey journey : leastStops) {
            if(journey.getArrivalTime()<quickestArrival)
                firstAtTheEnd=journey;
        }
        this.optimal=firstAtTheEnd;

    } 

}


